<!DOCTYPE html>
<html>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="divport"
		content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, divport-fit=cover">
	<link rel="stylesheet" href="../../css/all.css">
	<link rel="stylesheet" href="../../css/style.css">
	<link rel="stylesheet" type="text/css" href="../../css/vant.css" />
	<link rel="stylesheet" type="text/css" href="../../css/tabbar.css" />
	<script src="../../js/rem.js"></script>
	<script src="../../js/jquery-3.6.0.min.js"></script>
	<title>游戏阁</title>
	<style type="text/css">
		/* 根元素样式 设置页面背景、字体大小、字体颜色，字符间距、长单词换行 */
		body {
			background: #F1F1F3;
			word-wrap: break-word;
		}

		/* 列式弹性盒子 */
		.flex_col {
			display: flex;
			flex-direction: row;
			flex-wrap: nowrap;
			justify-content: flex-start;
			align-items: center;
			align-content: center;
			font-size: 0.24rem;
		}

		/* 弹性盒子弹性容器 */
		.flex_col .flex_grow {
			width: 0;
			flex-grow: 1;
			position: relative;
		}

		/* 对齐方式 */
		.align_c {
			text-align: center;
		}

		/* 加载数据提示 */
		.tips {
			position: fixed;
			left: 0;
			top: 0.88rem;
			width: 100%;
			z-index: 9;
			background-color: rgba(0, 0, 0, 0.15);
			height: 0.72rem;
			line-height: 0.72rem;
			transform: translateY(-0.80rem);
			transition: transform 0.3s ease-in-out 0s;
			color: #fff;
			font-size: 0.24rem;
		}

		.show {
			transform: translateY(0);
		}

		.box-1 {
			width: 100%;
			height: auto;
			padding-bottom: 1rem;
			box-sizing: content-box;
			/* 兼容iPhoneX */
			margin-bottom: 0;
			margin-bottom: constant(safe-area-inset-bottom);
			margin-bottom: env(safe-area-inset-bottom);
		}

		.box-2 {
			position: fixed;
			left: 0;
			width: 100%;
			bottom: 0;
			height: auto;
			z-index: 2;
			border-top: #e5e5e5 solid 1px;
			box-sizing: content-box;
			background-color: #F3F3F3;
			/* 兼容iPhoneX */
			padding-bottom: 0;
			padding-bottom: constant(safe-area-inset-bottom);
			padding-bottom: env(safe-area-inset-bottom);

		}

		.box-2 .content {
			background-color: #fff;
			height: 0.64rem;
			padding: 0 0.2rem;
			border-radius: 16px;
			font-size: 0.28rem;
			width: 100%;
		}

		.box-2 .send {
			background-color: #42b983;
			color: #fff;
			height: 0.64rem;
			margin-left: 0.2rem;
			border-radius: 16px;
			padding: 0;
			width: 1.2rem;
			line-height: 0.62rem;

		}

		.box-2 .send:active {
			background-color: #5fc496;
		}

		.box-2>div {
			padding: 0 0.4rem;
			height: 1rem;
		}

		.talk-list .item .pic {
			width: 0.92rem;
			height: 0.92rem;
			border-radius: 50%;
			border: #fff solid 1px;
		}

		.talk-list .item .content {
			padding: 0.2rem;
			border-radius: 10px;
			max-width: 5rem;
			word-break: break-all;
			line-height: 0.52rem;
			position: relative;
		}

		.talk-list .item {
			padding: 0.2rem 0.2rem 0 0.2rem;
			align-items: flex-start;
			align-content: flex-start;
			color: #333;
		}

		.pull .content {
			margin-left: 0.32rem;
			background-color: #fff;
		}

		.pull .content::after {
			content: '';
			display: block;
			width: 0;
			height: 0;
			border-top: 0.16rem solid transparent;
			border-bottom: 0.16rem solid transparent;
			border-right: 0.2rem solid #fff;
			position: absolute;
			top: 0.3rem;
			left: -0.18rem;
		}

		/* 发出的消息 */
		.push {
			/* 主轴为水平方向，起点在右端。使不修改DOM结构，也能改变元素排列顺序 */
			flex-direction: row-reverse;
		}

		.push .content {
			margin-right: 0.32rem;
			background-color: #337EFB;
			color: #fff;
		}

		.push .content::after {
			content: '';
			display: block;
			width: 0;
			height: 0;
			border-top: 0.16rem solid transparent;
			border-bottom: 0.16rem solid transparent;
			border-left: 0.2rem solid #337EFB;
			position: absolute;
			top: 0.15rem;
			right: -0.09rem;
		}

		.talk-list {
			padding-bottom: 0.2rem;
		}

		.nav {
			background: #fff;
		}

		.content {
			padding-top: 0.88rem;
		}

		.van-toast--text {
			padding: 0.16rem 0.24rem;
			min-width: 1.82rem;
			font-size: 0.28rem;
		}

		.add {
			width: 0.42rem;
			height: 0.42rem;
		}

		.emo {
			position: absolute;
			top: 0;
			bottom: 0;
			margin: auto;
			right: 0.2rem;
		}
		.add_box{
			margin-left: 0.16rem;
		}
	</style>
	<body>
		<div id="app" v-cloak>
			<div class="content">
				<div class="nav">
					<div class="back_box">
						<img src="../../img/back2.png" class="back2" @click="back">
					</div>
					<p class="nav_black">联系客服</p>
					<div class="searchs">
					</div>
				</div>
				<div>
					<div class="tips  align_c" :class="{ 'show':ajax.loading }" @click="getHistoryMsg">
						{{ajax.loadText}}
					</div>
					<div class="box-1" id="list-box">
						<div class="talk-list">
							<div v-for="(item,index) in talkList" :key="index" :id="`msg-${item.id}`">
								<div class="item flex_col" :class=" item.type == 1 ? 'push':'pull' ">
									<img :src="item.pic" class="pic">
									<div class="content">{{item.content}}</div>
								</div>
							</div>
						</div>
					</div>
					<div class="box-2">
						<div class="flex_col">
							<div class="flex_grow">
								<input type="text" class="content" v-model="content" placeholder="输入消息"
									placeholder-style="color:#DDD;" :cursor-spacing="6">
								<img src="../../img/cs/emo.png" class="add emo">
							</div>
							<!-- <div class="add_box">
								<img src="../../img/cs/add.png" class="add">
							</div> -->
							<button class="send" @click="send">发送</button>
						</div>
					</div>
				</div>

			</div>
		</div>
	</body>
	<script src="../../js/vue.js" type="text/javascript" charset="utf-8"></script>
	<script src="../../js/api.js" type="text/javascript" charset="utf-8"></script>
	<script src="../../js/vant.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		Vue.use(vant.Toast);
		new Vue({
			el: '#app',
			data() {
				return {
					talkList: [],
					ajax: {
						rows: 20, //每页数量
						page: 1, //页码
						flag: true, // 请求开关
						loading: true, // 加载中
						loadText: '正在获取消息'
					},
					content: ''
				}
			},
			mounted() {
				var that = this
				this.$nextTick(() => {
					this.getHistoryMsg();
				});
				window.addEventListener("scroll", function(event) {
					var scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body
						.scrollTop;
					if (scrollTop == 0) {
						that.getHistoryMsg();
					}
				});
			},
			methods: {
				// 获取历史消息
				getHistoryMsg(t) {
					if (!this.ajax.flag) {
						return; //
					}
					// 此处用到 ES7 的 async/await 知识，为使代码更加优美。不懂的请自行学习。
					let get = async () => {
						this.hideLoadTips();
						this.ajax.flag = false;
						let data = await this.joinHistoryMsg();
						console.log('----- 模拟数据格式，供参考 -----');
						console.log(data); // 查看请求返回的数据结构 
						// 获取待滚动元素选择器，解决插入数据后，滚动条定位时使用
						let selector = '';

						if (this.ajax.page > 1) {
							// 非第一页，则取历史消息数据的第一条信息元素
							selector = `#msg-${this.talkList[0].id}`;
						} else {
							// 第一页，则取当前消息数据的最后一条信息元素
							selector = `#msg-${data[data.length-1].id}`;
						}
						console.log(selector)
						// 将获取到的消息数据合并到消息数组中
						this.talkList = [...data, ...this.talkList];

						// 数据挂载后执行，不懂的请自行阅读 Vue.js 文档对 Vue.nextTick 函数说明。
						this.$nextTick(() => {
							// 设置当前滚动的位置
							this.setPageScrollTo(selector);
							this.hideLoadTips(true);
							if (data.length < this.ajax.rows) {
								// 当前消息数据条数小于请求要求条数时，则无更多消息，不再允许请求。
								// 可在此处编写无更多消息数据时的逻辑
							} else {
								this.ajax.page++;
								// 延迟 200ms ，以保证设置窗口滚动已完成
								setTimeout(() => {
									this.ajax.flag = true;
								}, 200)
							}

						})
					}
					get();
				},
				// 发送信息
				send() {
					if (!this.content) {
						vant.Toast('请输入内容')
						return;
					}
					setTimeout(() => {
						// 将当前发送信息 添加到消息列表。
						let data = {
							"id": new Date().getTime(),
							"content": this.content,
							"type": 1,
							"pic": "../../img/login/logo.png"
						}
						this.talkList.push(data);
						this.$nextTick(() => {
							// 清空内容框中的内容
							this.content = '';
							document.documentElement.scrollTop = 99999
						})
					}, 500);
				},
				// 隐藏加载提示
				hideLoadTips(flag) {
					if (flag) {
						this.ajax.loadText = '消息获取成功';
						setTimeout(() => {
							this.ajax.loading = false;
						}, 300);
					} else {
						this.ajax.loading = true;
						this.ajax.loadText = '正在获取消息';
					}
				},
				// 拼接历史记录消息，正式项目可替换为请求历史记录接口
				joinHistoryMsg() {
					let join = () => {
						let arr = [];
						//通过当前页码及页数，模拟数据内容
						let startIndex = (this.ajax.page - 1) * this.ajax.rows;
						let endIndex = startIndex + this.ajax.rows;
						for (let i = startIndex; i < endIndex; i++) {
							arr.push({
								"id": i, // 消息的ID
								"content": `这是历史记录的第${i+1}条消息`, // 消息内容
								"type": Math.random() > 0.5 ? 1 : 0, // 此为消息类别，设 1 为发出去的消息，0 为收到对方的消息,
								"pic": "../../img/login/logo.png" // 头像
							})
						}

						/*
							颠倒数组中元素的顺序。将最新的数据排在本次接口返回数据的最后面。
							后端接口按 消息的时间降序查找出当前页的数据后，再将本页数据按消息时间降序排序返回。
							这是数据的重点，因为页面滚动条和上拉加载历史的问题。
						 */
						arr.reverse();

						return arr;
					}

					// 此处用到 ES6 的 Promise 知识，不懂的请自行学习。
					return new Promise((done, fail) => {
						// 无数据请求接口，由 setTimeout 模拟，正式项目替换为 ajax 即可。
						setTimeout(() => {
							let data = join();
							done(data);
						}, 1500);
					})
				},
				// 设置页面滚动位置
				setPageScrollTo(selector) {
					console.log(selector)
					console.log()
					let top = document.querySelector(selector).offsetTop
					document.documentElement.scrollTop = top - 220
				},

			}
		})
	</script>
</html>
